<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/16
 * Time: 21:00
 */
namespace Pay\Controller;

use Common\Common\Api\Order;
use Common\Common\Api\Ordermember;
use Common\Common\Api\Redis\Channel;
use Common\Common\Api\Redis\Product;

/**
 * Class ManyiController
 * @package Pay\Controller
 * 贝利
 */
class BeiliController extends PayController{
    protected $config;
    protected $class;
    private $merchant_private_key;
    private $merchant_public_key;
    private $web_public_key;

    public function __construct(){
        parent::__construct();
        $classes = explode("\\",__CLASS__);
        $class = end($classes);
        $this->class = substr($class, 0, stripos($class, "Controller"));


        $this->merchant_private_key = file_get_contents("Files/".$this->class."/merchant_private_key.txt");
        $this->merchant_public_key = file_get_contents("Files/".$this->class."/merchant_public_key.txt");
        $this->web_public_key = file_get_contents("Files/".$this->class."/web_public_key.txt");
    }

    public function pay($array){
        $this->config = Channel::getInstance()->getById($array['channel']);

        if(!$this->config){
            $this->showmessage('通道错误!',['code'=>C("THIRDCODES.".$this->class)]);
        }

        $product = Product::getInstance()->getById(I("request.pay_bankcode",0,"intval"));

        if(!$product){
            $this->showmessage('未找到支付产品!',['code'=>C("THIRDCODES.".$this->class)]);
        }

        $parameter = array(
            'code' => $this->config['code'], // 通道名称
            'title' => $this->config['title'],
            'exchange' => 1, // 金额比例
            'gateway' => $this->config['gateway'],
            'orderid' => createOrderId(),
            'out_trade_id' => I("request.pay_orderid"),
            'body' => 'pay',
            'channel'=>$array
        );

        $return = $this->orderadd( $parameter );

        switch($this->config['paytype']){
            case 11:
                $code = $this->juhe($return,$product);
                break;
            default:
                $this->wangguan($return,$product);
        }
        
        //返回json
        if($_REQUEST['pay_returntype']){
            $this->showJson("", $code);
        }

        $paytype = transArr( C("PAYTYPES"), "id");

        $this->assign("title", $paytype[$this->config['paytype']]);
        $this->assign("return", $return);
        $this->assign("imgurl", C("website.DOMAIN")."/Pay_Qrcode_getCode?type=1&data=" . $code);

        switch($this->config['paytype']){
            //微信
            case 1:
                $this->display("WeiXin/weixin");
                break;
            //支付宝扫码
            case 3:
                //支付宝H5
            case 4:
                if(isMobile()){
                    $this->display("WeiXin/alipaywap");
                }else{
                    $this->display("WeiXin/alipay");
                }
                break;
            default:
                $this->display("WeiXin/Pay");
        }
    }

    //聚合支付
    private function juhe($return, $product){
        $isMobile = isMobile();

        $data = array();
        $data['orderNumber'] = $return['orderid'];
        $data['amount'] = intval($return['amount']*100);
        $data['currency'] = 'CNY';
        $data['commodityName'] = 'compu';
        $data['commodityDesc'] = 'nice';
        $data['vaildTime'] = '120';
        switch($this->config['paytype']) {
            //银联扫码
            case 11:
                $data['payType'] = 'UNION_NATIVE';
                break;
            default:
                $this->showmessage('暂不支持此支付方式!',['code'=>C("THIRDCODES.".$this->class)]);
        }
        $data['cardType'] = 'SAVINGS';
        $data['returnUrl'] = $return['callbackurl'];
        $data['notifyUrl'] = $return['notifyurl'];
        $data['orderCreateIp'] = getIP();

        ksort($data);
        $json_businessContext = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $mer_private_key = openssl_pkey_get_private($this->merchant_private_key);

        openssl_sign($json_businessContext, $sign, $mer_private_key, OPENSSL_ALGO_MD5);
        $sign = base64_encode($sign);


        $businessHead = array(
            'charset' =>'00',
            'version'=>'V1.1.0',
            'merchantNumber'=> $this->config['mch_id'],
            'requestTime'=>date("YmdHis",time()),
            'signType'=>'RSA',
            'sign'=>'',
        );
        $businessHead['sign'] = $sign;

        $arr_order['businessHead'] = $businessHead;
        $arr_order['businessContext'] = $data;

        $json_order = json_encode($arr_order, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

        $ec_public_key = openssl_pkey_get_public($this->web_public_key);
        $cryptos = $this->rsa_encrypt($json_order, $ec_public_key);

        $context = array(
            'context' => $cryptos,
        );

        $res = curl_json($this->config['gateway']."/api/payment/unifiedPay", $context);

        $res = json_decode($res, true);
        if(!$res || empty($res)){
            $this->showmessage('获取数据失败!',['code'=>C("THIRDCODES.".$this->class)]);
        }

        if($res['message']['code'] !== 200){
            if($res['message']['content']){
                $this->showmessage($res['message']['content'],['code'=>C("THIRDCODES.".$this->class)]);
            }
            $this->showmessage('未知错误!',['code'=>C("THIRDCODES.".$this->class)]);
        }

        $context = $res['context'];
        $decode = $this->rsa_decrypt($context, $mer_private_key);

        $decode = json_decode($decode, true);
        if(!$decode || empty($decode)){
            $this->showmessage('获取验签数据失败!',['code'=>C("THIRDCODES.".$this->class)]);
        }

        $code = $decode['businessContext']['payurl'];

        if(!$code){
            $this->showmessage('获取支付链接失败!',['code'=>C("THIRDCODES.".$this->class)]);
        }

        return $code;
    }

    //网关支付
    private function wangguan($return,$product){
        $isMobile = isMobile();

        $data = array();
        $data['orderNumber'] = $return['orderid'];
        $data['amount'] = intval($return['amount']*100);
        $data['currency'] = 'CNY';
        $data['commodityName'] = 'compu';
        $data['commodityDesc'] = 'nice';
        $data['vaildTime'] = '120';
        switch($this->config['paytype']) {
            //银联快捷
            case 13:
                $data['payType'] = 'QUICK';
                $data['userId'] = mt_rand(100000,999999);
                break;
            //银联扫码
            case 11:
                $data['payType'] = '';
                break;
            //网银直连
            case 6:
                $data['payType'] = 'B2C';

                switch($product['code']){
                    //北京银行
                    case 'BOB':
                        $data['bankNumber'] = '1016';
                        break;
                    //东亚银行
                    case 'BEA':
                        $data['bankNumber'] = '1203';
                        break;
                    //中国工商银行
                    case 'ICBC':
                        $data['bankNumber'] = '1001';
                        break;
                    //光大银行
                    case 'CEB':
                        $data['bankNumber'] = '1008';
                        break;
                    //广发银行
                    case 'CGB':
                        $data['bankNumber'] = '1017';
                        break;
                    //华夏银行
                    case 'HXB':
                        $data['bankNumber'] = '1009';
                        break;
                    //中国建设银行
                    case 'CCB':
                        $data['bankNumber'] = '1004';
                        break;
                    //交通银行
                    case 'BOCOM':
                        $data['bankNumber'] = '1005';
                        break;
                    //中国民生银行
                    case 'CMBC':
                        $data['bankNumber'] = '1010';
                        break;
                    //南京银行
                    case 'NJCB':
                        $data['bankNumber'] = '1201';
                        break;
                    //宁波银行
                    case 'NBCB':
                        $data['bankNumber'] = '1202';
                        break;
                    //中国农业银行
                    case 'ABC':
                        $data['bankNumber'] = '1002';
                        break;
                    //平安银行
                    case 'PAB':
                        $data['bankNumber'] = '1011';
                        break;
                    //上海银行
                    case 'SHB':
                        $data['bankNumber'] = '1025';
                        break;
                    //上海浦东发展银行
                    case 'SPDB':
                        $this->showmessage('暂不支持此银行卡!',['code'=>C("THIRDCODES.".$this->class)]);
                        break;
                    //深圳发展银行
                    case 'SDB':
                        $this->showmessage('暂不支持此银行卡!',['code'=>C("THIRDCODES.".$this->class)]);
                        break;
                    //兴业银行
                    case 'CIB':
                        $data['bankNumber'] = '1013';
                        break;
                    //中国邮政储蓄银行
                    case 'PSBS':
                        $data['bankNumber'] = '1006';
                        break;
                    //招商银行
                    case 'CMB':
                        $data['bankNumber'] = '1012';
                        break;
                    //浙商银行
                    case 'CZB':
                        $this->showmessage('暂不支持此银行卡!',['code'=>C("THIRDCODES.".$this->class)]);
                        break;
                    //中国银行
                    case 'BOC':
                        $data['bankNumber'] = '1003';
                        break;
                    //中信银行
                    case 'CTTIC':
                        $data['bankNumber'] = '1007';
                        break;
                    default:
                        $this->showmessage('暂不支持此银行卡!',['code'=>C("THIRDCODES.".$this->class)]);
                }
                break;
            default:
                $this->showmessage('暂不支持此支付方式!',['code'=>C("THIRDCODES.".$this->class)]);
        }
        $data['cardType'] = 'SAVINGS';
        $data['returnUrl'] = $return['callbackurl'];
        $data['notifyUrl'] = $return['notifyurl'];

        ksort($data);
        $json_businessContext = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $mer_private_key = openssl_pkey_get_private($this->merchant_private_key);

        openssl_sign($json_businessContext, $sign, $mer_private_key, OPENSSL_ALGO_MD5);
        $sign = base64_encode($sign);


        $businessHead = array(
            'charset' =>'00',
            'version'=>'V1.1.0',
            'merchantNumber'=> $this->config['mch_id'],
            'requestTime'=>date("YmdHis",time()),
            'signType'=>'RSA',
            'sign'=>'',
        );
        $businessHead['sign'] = $sign;

        $arr_order['businessHead'] = $businessHead;
        $arr_order['businessContext'] = $data;

        $json_order = json_encode($arr_order, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

        $ec_public_key = openssl_pkey_get_public($this->web_public_key);
        $cryptos = $this->rsa_encrypt($json_order, $ec_public_key);

        //echo '<pre/>';print_r($data); exit;

        header("Location:".$this->config['gateway']."/api/payment/gatewayPay?context=".$cryptos); exit;
    }

    function rsa_encrypt($encrypted, $rsa_public_key){
        $crypto = '';
        foreach (str_split($encrypted, 117) as $chunk) {
            openssl_public_encrypt($chunk, $encryptDatas, $rsa_public_key);
            $crypto .= $encryptDatas;
        }
        return base64_encode($crypto);
    }

    function rsa_decrypt($encrypted, $rsa_private_key){
        $crypto = '';
        $encrypted = base64_decode($encrypted);
        foreach (str_split($encrypted, 128) as $chunk) {
            openssl_private_decrypt($chunk, $decryptData, $rsa_private_key);
            $crypto .= $decryptData;
        }
        return $crypto;
    }

    //通知
    public function notifyurl(){
        //file_put_contents("a.txt",var_export($_POST,true)."\r\n\r\n");
        //file_put_contents("a.txt",var_export($_GET,true)."\r\n\r\n", FILE_APPEND);
        //file_put_contents("a.txt", file_get_contents('php://input')."\r\n\r\n", FILE_APPEND);
        //file_put_contents("a.txt", date("Y-m-d H:i:s",time())."\r\n\r\n", FILE_APPEND);

        $p = $origin = file_get_contents('php://input');

        //$p = '{"merchantNumber":"PAY000118000170","orderNumber":"2018111815083698552","context":"R0hGubO0ODtXtnXj7LhBZblrmImhE2e7lqhVASbiw/E2s9atGHmLC1Uw1TUluzElkcN/U/8Ws40sFm/irPe6OUOIrE9x3AME6J5Uv/5AhWCpeuzs5aYGSaw5UFsCLU/weqYUTLDWW6jikAOYj1nyEtjKr4oAxu3JAPlvrs/t8PiAktx+X3VxTcutrXj4NhczV/2uwSf3qzvL41MpFUdc0dOYTgi8X2uM91kitq0bSTrZeVP7nbUhWklzusa28QfFy9vI+Pk3hG5Aaui+5usDJlGXbGeNY8xNpEM0A1GnE8+lGVyHssNxnDAVLFDwQX/2V+vobnwTax2I+86PZun3WSF1P0zq7Lo5b2LFfbTh5LjRbNPBmf3uP66OREWHwGJDn835tHWfCcSelkgb6mPcb15VoXeHEFlmmhcGe6GwHowQgCmTUvfHJrSjzXiw6jiVAM5ljs/NZZp23ueygDrBiB+1/SotljHzwHuiB3AYZXaJjRjxRjLYn+LDkU8lK+f0Ncea2OYn59SvkV7PCb58OyCVFeHYgdflK03Rz5lTZYt7lEmpz9I0S2A0qW7DVLT7eBDeHjP7m0Xxlj8rSUGRrQcIu1CunlDTHuxn6fLYOw/lJokHMTsdVKDH7Sk3DtTPHX1ffLVvWYAcwgeQ0IuqrbDI4RTiOZ9iDMc43X1uFDA="}';

        $p = json_decode($p, true);

        /*
         * Array
            (
                [merchantNumber] => PAY000118000170
                [orderNumber] => 2018111815083698552
                [context] => R0hGubO0ODtXtnXj7LhBZblrmImhE2e7lqhVASbiw/E2s9atGHmLC1Uw1TUluzElkcN/U/8Ws40sFm/irPe6OUOIrE9x3AME6J5Uv/5AhWCpeuzs5aYGSaw5UFsCLU/weqYUTLDWW6jikAOYj1nyEtjKr4oAxu3JAPlvrs/t8PiAktx+X3VxTcutrXj4NhczV/2uwSf3qzvL41MpFUdc0dOYTgi8X2uM91kitq0bSTrZeVP7nbUhWklzusa28QfFy9vI+Pk3hG5Aaui+5usDJlGXbGeNY8xNpEM0A1GnE8+lGVyHssNxnDAVLFDwQX/2V+vobnwTax2I+86PZun3WSF1P0zq7Lo5b2LFfbTh5LjRbNPBmf3uP66OREWHwGJDn835tHWfCcSelkgb6mPcb15VoXeHEFlmmhcGe6GwHowQgCmTUvfHJrSjzXiw6jiVAM5ljs/NZZp23ueygDrBiB+1/SotljHzwHuiB3AYZXaJjRjxRjLYn+LDkU8lK+f0Ncea2OYn59SvkV7PCb58OyCVFeHYgdflK03Rz5lTZYt7lEmpz9I0S2A0qW7DVLT7eBDeHjP7m0Xxlj8rSUGRrQcIu1CunlDTHuxn6fLYOw/lJokHMTsdVKDH7Sk3DtTPHX1ffLVvWYAcwgeQ0IuqrbDI4RTiOZ9iDMc43X1uFDA=
            )
         */

        if(!$p || empty($p)){
            exit("wrong");
        }

        //获取订单信息
        $orderid = $p['orderNumber'];
        $find = M("Order")->where(array("pay_orderid"=>$orderid))->find();
        if(!$find){
            echo 'order_not_found'; exit;
        }

        //保存回调数据
        M("Order")->where(array("pay_orderid"=>$orderid))->save(array(
            "server_return"=> $origin,
            //"pay_orderid_rd"=>$p['sysnumber']
        ));

        //获取渠道信息
        $this->config = M("Channel")->where(array('code'=>$this->class))->find();

        $notify = $p['context'];

        $mer_private_key = openssl_pkey_get_private($this->merchant_private_key);

        $ec_public_key = openssl_pkey_get_public($this->web_public_key);
        $data = $this->rsa_decrypt($notify, $mer_private_key);//执行解密流程

        $context_arr = json_decode($data, true);//转为数组格式

        if(!$context_arr || empty($context_arr)){
            echo "uncompile_failed"; exit;
        }

        if($context_arr['businessContext']['orderStatus'] !== 'SUC'){
            echo "pay_fail"; exit;
        }

        $sign = $context_arr['businessHead']['sign'];//取SIGN
        $businessContext = $context_arr['businessContext'];//取businessContext

        ksort($businessContext);//按ASCII码从小到大排序

        $json_businessContext = json_encode($businessContext, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $isVerify = openssl_verify($json_businessContext, base64_decode($sign), $ec_public_key, OPENSSL_ALGO_MD5);

        if(!$isVerify){
            echo "sign_wrong"; exit;
        }

        //回调成功
        //echo 200; exit;
        $this->async($find['pay_orderid'],'SUC');
    }

    public function callBackUrl(){

        echo '处理成功'; exit;
    }
}